import {EditFilled, PlusOutlined, UsergroupAddOutlined} from '@ant-design/icons';
import {Avatar, Button, message, Upload} from 'antd';
import React, { useState, useRef } from 'react';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import type { ProColumns, ActionType} from '@ant-design/pro-table';
import ImgCrop from 'antd-img-crop';
import type { ProFormInstance} from '@ant-design/pro-form';
import {
  ModalForm,
  ProForm,
  ProFormSelect, ProFormSwitch,
  ProFormText,
  ProFormTreeSelect,
} from '@ant-design/pro-form';
import {
  ProTable,
} from '@ant-design/pro-table';

import type { FormValueType } from './components/UpdateForm';
import UpdateForm from './components/UpdateForm';
// 公用接口
import {  queryDeptTree, queryRoleItem, queryUserItem } from '../service';
// 专用接口
import {queryUserList, addUser, updateUser, lockUser} from './service'
import type { UserItem, TableListPagination } from './data';
import type { RequestOptionsType } from '@ant-design/pro-utils';
import type {UploadProps} from "antd/es";
import type {RcFile, UploadFile} from "antd/es/upload/interface";
import PermsForm from './components/PermsForm';
import {LockOutline} from "antd-mobile-icons";

/**
 * 添加节点
 *
 * @param fields
 */

const handleAdd = async (fields: UserItem) => {
  const hide = message.loading('正在添加用户...');

  try {
    const res = await addUser({...fields});
    if(res && res.status === "done"){
      hide();
      message.success(res.message);
      return true;
    }else {
      hide()
      message.error(res.message);
      return false;
    }
  } catch (error) {
    hide();
    message.error('添加失败请重试！');
    return false;
  }
};

/**
 * 更新节点
 *
 * @param fields
 * @param currentRow
 */

const handleUpdate = async (fields: FormValueType, currentRow?: UserItem) => {
  const hide = message.loading('正在修改');

  try {
    const res = await updateUser({
      id: currentRow?.id,
      ...fields,
    });
    if(res && res.status === "done" ){
      hide();
      message.success(res.message);
      return true;
    }else {
      hide()
      message.error(res.message);
      return false;
    }
  } catch (error) {
    hide();
    message.error('用户更新失败，请重试！');
    return false;
  }
};
/**
 * 批量禁用用户节点
 *
 * @param selectedRows
 */

const handleRemove = async (selectedRows: UserItem[]) => {
  const hide = message.loading('正在禁用');
  if (!selectedRows) return true;

  try {
    const res = await lockUser({
      key: selectedRows.map((row) => row.id),
    });
    hide();
    if (res){
      if (res.status === "done"){
        message.success(res.message)
        return true
      }else {
        message.error(res.message)
        return false
      }
    }else {
      message.error('禁用失败，请重试');
      return false
    }
  } catch (error) {
    hide();
    message.error('禁用失败，请重试');
    return false;
  }
};

/**
 * 禁用单用户节点
 *
 * @param user
 */

const handleSingleRemove = async (user: UserItem) => {
  const hide = message.loading('正在禁用');
  try {
    const res = await lockUser({
      key: [user.id],
    });
    hide();
    if (res){
      if (res.status === "done"){
        message.success(res.message)
        return true
      }else {
        message.error(res.message)
        return false
      }
    }else {
      message.error('禁用失败，请重试');
      return false
    }
  } catch (error) {
    hide();
    message.error('禁用失败，请重试');
    return false;
  }
};

const TableList: React.FC = () => {
  /** 新建窗口的弹窗 */
  const [createModalVisible, handleModalVisible] = useState<boolean>(false);

  /** 分布更新窗口的弹窗 */
  const [updateModalVisible, handleUpdateModalVisible] = useState<boolean>(false);

  /** 权限窗口 */
  const [permsModalVisible, handlePermsModalVisible] = useState<boolean>(false);

  const actionRef = useRef<ActionType>();
  const [currentRow, setCurrentRow] = useState<UserItem>();
  const [selectedRowsState, setSelectedRows] = useState<UserItem[]>([]);
  /** 国际化配置 */
  /** ModalForm中头像上传的预览 */
  const [fileList, setFileList] = useState<UploadFile[]>([
    // {
    //   uid: '-1',
    //   name: 'image.png',
    //   status: 'done',
    //   url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    // },
  ]);

  // ModalForm更新入口
  const formRef = useRef<ProFormInstance>();
  const onChange: UploadProps['onChange'] = ({file,fileList: newFileList }) => {
    // 上传文件
    setFileList(newFileList);
    // 获取返回
    const res = file.response;
    if(res){
      // 有返回结果时，进行判断
      if(res.status === "done"){
        // 保存成功，给Form回填数值
        /**
         * 由于ProForm的文件上传字段，并不包含在FORM表单中。无法在上传完毕后自动关联;
         * 1，在FORM中增加一个隐藏字段：
         *     <ProFormText name="avatar" hidden={true}/>
         * 2， 在ModalForm中增加 formRef={formRef} 属性
         * 3， 在处理文件上传的onchange函数前增加formRef入口
         *        // ModalForm更新入口
         *        const formRef = useRef<ProFormInstance>();
         * 4，上传完成时，给隐藏字段赋值：
         *         formRef?.current?.setFieldsValue({
         *           avatar: res.url
         *         })
         * 通过以上算步，可以将通过文件上传接口上传的文件，关联到当前FORM表单中。
         */

        formRef?.current?.setFieldsValue({
          avatar: res.url    // 可以绑定后台返回的name或者url，或者fid，根据需求，取对应的数据
        })
        // message.success(res.message)
      }else {
        // 后台返回错误，需要告知前台
        message.error(res.message).then()
      }
    }
  };

  const onPreview = async (file: UploadFile) => {
    let src = file.url as string;
    if (!src) {
      src = await new Promise(resolve => {
        const reader = new FileReader();
        reader.readAsDataURL(file.originFileObj as RcFile);
        reader.onload = () => resolve(reader.result as string);
      });
    }
    const image = new Image();
    image.src = src;
    const imgWindow = window.open(src);
    imgWindow?.document.write(image.outerHTML);
  };

  // 表头，列表渲染设置
  const columns: ProColumns<UserItem>[] = [
    // 关键字搜索
    {
      title: "keyword",
      hideInTable: true,
      hideInForm: true,
      dataIndex: 'keyword',
      formItemProps: {label: '关键字'}
    },

    // 按状态搜索
    {
      title: '状态',
      dataIndex: 'isActive',
      sorter: false,
      hideInSearch: false,
      hideInTable: true,
      valueType: 'switch',
      fieldProps: {
        checkedChildren: "有效",
        unCheckedChildren: "禁用",
        defaultChecked: true,
      },
    },
    // 列表字段
    {
      title: 'ID',
      // copyable: true,  // 展示复制按钮
      dataIndex: 'id', // 数据索引
      // ellipsis: true,  // 超长度自动收缩
      // tip: 'ID',    // 提示文字tip
      sorter: (a, b) => a.id - b.id,    // 开启排序
      search: false,   // 是否在header展示此搜索框
      hideInTable: false,  // 不在表格中展示
      hideInSearch: true,  // 不在搜索框中展示
    },
    {
      title: '用户名',
      dataIndex: 'username',
      valueType: 'text',
      hideInSearch: true,
    },
    {
      title: '姓名',
      dataIndex: 'nick_name',
      hideInSearch: true,
      valueType: 'text',
      render: (_, {nickname,avatar}) => (
        <>
        <Avatar size="small" src={avatar} alt="avatar">Null</Avatar>
          {nickname}
        </>
      )
    },
    {
      title: '性别',
      hideInSearch: true,
      dataIndex: 'gender',
      valueEnum: {
        1: {
          text: '男',
          status: 'Processing',
        },
        0: {
          text: '女',
          status: 'Error',
        },
        2: {
          text: '其他',
          status: 'Success',
        },
      },
    },
    {
      title: '手机号码',
      dataIndex: 'mobile',
      hideInSearch: true,
      valueType: "text",
      // renderText: (val: string) => `${val}`,
    },
    {
      title: '邮箱',
      dataIndex: 'email',
      hideInSearch: true,
      valueType: "text",
      // renderText: (val: string) => `${val}`,
    },
    {
      title: '上次登录',
      dataIndex: 'lastLoginTime',
      hideInSearch: true,
      valueType: "dateTime",
      sorter: (a, b) => {
        // 开启排序
        // 时间的排序，需要先转存时间戳
        const aTime = new Date(a.lastLoginTime).getTime();
        const bTime = new Date(b.lastLoginTime).getTime();
        return aTime - bTime
      }

    },
    {
      title: '操作',
      dataIndex: 'option',
      valueType: 'option',
      align: 'right',
      fixed: "right",
      width: 180,
      render: (_, record) => [
        <a
          key="config"
          onClick={() => {
            handleUpdateModalVisible(true);
            setCurrentRow(record);
          }}
        ><EditFilled/> 修改</a>,
        <a
          key="deny"
          style={{
            color: "gray",
          }}
          onClick={() => {
            handleSingleRemove(record).then(actionRef?.current?.reload)
          }}
        ><LockOutline /> 禁用</a>,
        <a
          key="subscribeAlert"
          style={{color: "#fa8c16"}}
          onClick={() => {
             handlePermsModalVisible(true);
             setCurrentRow(record);
           }}
        ><UsergroupAddOutlined/> 权限</a>,
      ],
    },
  ];

  return (
    <PageContainer  pageHeaderRender={false}>
      <ProTable<UserItem, TableListPagination>
        scroll={{x: 'max-content'}}
        headerTitle="用户列表"
        actionRef={actionRef}
        rowKey="id"
        search={
          {}
        }
        // 设置分页参数
        pagination={{defaultPageSize: 10,}}
        toolBarRender={() => [
          <Button
            type="primary"
            key="primary"
            onClick={() => {
              handleModalVisible(true);
            }}
          >
            <PlusOutlined/> 新建
          </Button>,
        ]}
        //
        request={queryUserList}
        columns={columns}
        rowSelection={{
          onChange: (_, selectedRows) => {
            setSelectedRows(selectedRows);
          },
        }}
      />
      {selectedRowsState?.length > 0 && (
        <FooterToolbar
          extra={
            <div>
              已选择{' '}
              <a
                style={{
                  fontWeight: 600,
                }}
              >
                {selectedRowsState.length}
              </a>{' '}
              项 &nbsp;&nbsp;
              <span>
                {/*服务调用次数总计 {selectedRowsState.reduce((pre, item) => pre + item.callNo!, 0)} 万*/}
              </span>
            </div>
          }
        >
          <Button
            onClick={async () => {
              await handleRemove(selectedRowsState);
              setSelectedRows([]);
              actionRef.current?.reloadAndRest?.();
            }}
          >
            批量禁用
          </Button>
        </FooterToolbar>
      )}
      <ModalForm
          title="新建用户"
          // width="740px"   // 注销可由其自动管理宽度
          formRef={formRef}
          visible={createModalVisible}
          onVisibleChange={handleModalVisible}
          onFinish={async (value) => {
            const success = await handleAdd(value as UserItem);
            if (success) {
              handleModalVisible(false);
              if (actionRef.current) {
                actionRef.current.reload();
              }
            }
          }}
        >
          <ProForm.Group>
            <ProFormText
              rules={[
                {
                  required: true,
                  message: '用户名为必填项',
                },
              ]}
              width="sm"
              name="username"
              label={"用户名"}
            />
            <ProFormText
              width="sm"
              name="nickname"
              label={"姓名"}
              rules={[
                {
                  required: true,
                  message: '姓名为必填项',
                },
              ]}
            />
            <ProFormSelect
              name="gender"
              label={"性别"}
              width="sm"
              options={[
                {value: 1, label: "男"},
                {value: 0, label: "女"},
              ]}
              rules={[{required: true, message: '性别是必选项',},]}
            />
          </ProForm.Group>
          <ProForm.Group>
            <ProFormText
              width="md"
              name="email"
              label={"邮箱"}
              rules={[
                {required: true, message: '邮箱为必填项',},
                {pattern: /^[a-zA-Z\d_.-]+@[a-zA-Z\d-]+(\.[a-zA-Z\d-]+)*\.[a-zA-Z\d]{2,6}$/, message:'邮箱格式不正确！'},
                {max: 50, message:'邮箱不得超过50字符！'}
              ]}/>
            <ProFormText
              width="md"
              name="mobile"
              label={"手机号码"}
              rules={[
                { pattern: /^((13\d)|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18\d)|(19[8,9])|(166))\d{8}$/,
                  message:'手机号码格式不正确！'}
              ]}/>
          </ProForm.Group>
          <ProForm.Group>
            <ProFormTreeSelect
              label="部门"
              width="md"
              name="dept"
              fieldProps={{
                filterTreeNode: true,
                showSearch: true,                // 搜索功能
                multiple: true,                  // 多选
                // treeDefaultExpandAll: true,   // 默认展开所有节点
                treeCheckable: false,            // 选项前增加复选框，如果增加复选框，选中父节点时，子节点也会同步勾选
                treeDefaultExpandedKeys: [1],    // 只展开1级节点（2级节点可见）
                treeNodeFilterProp: 'title',     // 设置支持搜索中文（title）, 默认根据value来搜索的
              }}
              // 动态请求后端数据，形成Option
              request={async () => {
                const params = await queryDeptTree({pid: 0});
                let res: RequestOptionsType[] | PromiseLike<RequestOptionsType[]> | { label: any; value: any; }[] = [];
                if (params.success){
                  res = params.data
                }
                return res
              }}
            />
            <ProFormSelect
              label="直属领导"
              width="md"
              name="directLeader"
              showSearch={true}
              // 动态请求后端数据，形成Option
              request={async () => {
                const params = await queryUserItem();
                const res_leader: RequestOptionsType[] | PromiseLike<RequestOptionsType[]> | { label: any; value: any; }[] = [];
                if (params.success){
                  // eslint-disable-next-line array-callback-return
                  params.data.map((item: { username: any; id: any; }) => {
                    res_leader.push({ "label": item.username, "value": item.id })
                  })
                }
                return res_leader
              }}
            />
          </ProForm.Group>
          <ProForm.Group>
            <ProFormSelect
              label="角色"
              width="md"
              name="role"
              mode="multiple"
              // 动态请求后端数据，形成Option
              request={async () => {
                const params = await queryRoleItem();
                const res: RequestOptionsType[] | PromiseLike<RequestOptionsType[]> | { label: any; value: any; }[] = [];
                if (params.success){
                  // eslint-disable-next-line array-callback-return
                  params.data.map((item: { name: any; id: any; }) => {
                    res.push({ "label": item.name, "value": item.id })
                  })
                }
                return res
              }}
            />
            <ProFormText
              width="md"
              name="position"
              label={"职位"}
            />
          </ProForm.Group>
          <ProForm.Group>
            <ProFormText name="password" label="密码" width="sm" initialValue={"123456"} disabled />
            <ProFormText name="avatar" width="md" hidden={true}/>
            <ProFormSwitch checkedChildren="是" unCheckedChildren="否" width={"md"} name="isSuperuser" label="超级管理员" />
            <ProFormSwitch
              width={"md"}
              name="isActive"
              label="账号激活"
              checkedChildren="有效"
              unCheckedChildren="禁用"
              initialValue={true}
              fieldProps={{
                disabled: true,
              }}
            />
          </ProForm.Group>
          <ImgCrop>
            <Upload
              /**
               *   {fileList.length < 1 && '上传头像'}  设置上传数量限制
               *   action需要添加post上传文件的后端连接
               */
              name="file"
              accept="image/*"
              listType="picture-card"
              action="/api/upload?path=avatar"   // 上传接口，不支持添加到form的形式post上传
              fileList={fileList}
              onChange={onChange}
              onPreview={onPreview}
            >
              {fileList.length < 1 && '上传头像'}
            </Upload>
          </ImgCrop>
      </ModalForm>
      <UpdateForm
        onSubmit={async (value) => {
          const success = await handleUpdate(value, currentRow);

          if (success) {
            handleUpdateModalVisible(false);
            setCurrentRow(undefined);

            if (actionRef.current) {
              actionRef.current.reload();
            }
          }
        }}
        onCancel={() => {
          handleUpdateModalVisible(false);
          setCurrentRow(undefined);
        }}
        updateModalVisible={updateModalVisible}
        values={currentRow || {}}
      />
      <PermsForm
        onCancel={() => {
          handlePermsModalVisible(false);
          setCurrentRow(undefined);
        }}
        permsModalVisible={permsModalVisible}
        values={currentRow || {}}
      />
    </PageContainer>
  );
};

export default TableList;
